/*	Universidade de Brasília
	Instituto de Ciências Exatas
	Departamento de Ciências da Computação

	Organização de Arquivos - 1/2010 - Turma A - Prof.º Pedro Berger
	Trabalho 2 - Implementação da Árvore B

	08/32154 - Jefferson Leandro
	09/08860 - Eduardo Pires Fernandes
	09/10945 - João Paulo de Andrade Conti

	Desenvolvimento
		Compilador: GCC versão 4.4.3 padrão ANSI
		Sistema Operacional: Ubuntu 10.04 - Lucid Lynx
		Desenvolvimento utilizando repositório SVN

	Descrição
		O programa recebe um arquivo binário contendo registros e constrói um índice utilizando uma árvore B. O registro tem os campos matrícula e nome. A 			matrícula é a chave primária utilizada no índice. Um segundo programa recebe do usuário uma chave e retorna o segundo campo do registro (nome).
*/

/* Bibliotecas */
#include <stdio.h>
#include <stdlib.h>
#include "arvoreB.h"

int prr = 0; /* Variável global prr */

/* A função principal constrói a árvore de índices*/
int main () {
	/* Declaração de variáveis da função main */
	FILE *registros, *btree;	/* Arquivos de registros e da árvore B */
	int ordem;	/* Ordem da árvore */
	ptrArq arquivoReg, arquivoBTree;	/* Ponteiros de arquivos do registro e da árvore */
	ptrReg registro = NULL;	/* Ponteiro de registro */
	ptrPag raiz = NULL, atual = NULL;	/* Ponteiro de página raiz e atual */

	char c;	/* Lê caractere do arquivo */
	char nomeArq[31]; /* String que leva o nome do arquivo */

	/* Leitura da ordem k da árvore */
	printf ("Informe a ordem da arvore: ");
	scanf ("%d", &ordem);
	/* Validação da leitura da ordem entre 0 e 20 */
	while (ordem < 0 || ordem > 20) {
		printf ("Erro! A ordem deve ser menor que 20 e maior que 0.\n");
		printf ("Informe a ordem da arvore: ");
		scanf ("%d", &ordem);
	}

	/* Leitura do nome do arquivo de registros */
	printf ("Informe o nome do arquivo de registros: ");
	scanf ("%s", nomeArq);
	getchar ();
	/* Abertura e validação do arquivo binário */
	if ((registros = fopen (nomeArq, "rb")) == NULL) {
		printf ("Erro! Arquivo inexistente ou nao foi possivel abri-lo\n");
		exit (1);
	}
	else {
		printf ("Arquivo aberto com sucesso!\n");
	}

	arquivoReg = registros;	/* Ponteiro arquivoReg recebe o arquivo binário para tratamento das funções */

	/* Criação do registro raiz através de leitura do arquivo binário */
	if (fread (&c, 1, 1, registros) != 0) {
		registro = lerRegistro (&arquivoReg, c, prr);	/* Leitura do registro no arquivo e insere em uma página */
		prr = prr + 110;	/* Soma a prr do registro para facilitar recuperação */
		inicializaPagina (&raiz, &atual, &registro, ordem);	/* Cria página raiz*/
	}

	/* Leitura de todo arquivo de registros */
	while (fread (&c, 1, 1, registros) != 0) {
		registro = lerRegistro (&arquivoReg, c, prr);	/* Leitura do registro */
		prr = prr + 110;	/* Soma a prr do registro para facilitar recuperação */
		atual = insereElementoPagina (&raiz, registro->matricula, ordem);	/* Elemento encaixado na página */

		/* Verificação de espaço na página */
		if (verificaEspacoInsercaoRegistro (&atual, ordem)) {
			insereRegistro (&atual, &registro, ordem);	/* Inserção do registro */
			ordenaRegistros (&atual, ordem);	/* Ordenação da página */
			ordenaPonteiro (&atual, ordem);	/* Ordenação do ponteiro */
		}
		else {
			ordenaArvoreB (&raiz, &atual, &registro, ordem);	/* Reordenação da árvore executandodivisões e promoções */
		}

		atual = raiz;
	}

	fclose (registros);	/* Fechamento do arquivo de registros */
	btree = fopen ("arvoreB.bin", "wb");	/* Abertura do arquivo para escrita */
	arquivoBTree = btree;	/* Arquivo árvore recebe o arquivo binário para tratamento das funções */
	imprimePaginaArquivoIndice (&arquivoBTree, &raiz, ordem);	/* Impressão da página raiz no arquivo de índice */
	fclose (btree);	/* Fechamento do arquivo com índices criados */

	return 0;
}
